/**
 * ...
 * >author		João Vítor de Souza
 */

package com.cupcakeengine.core 
{
	import com.cupcakeengine.events.PreloaderEvent;
	import flash.display.DisplayObject;
	import flash.display.MovieClip;	
	import flash.errors.IllegalOperationError;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.utils.getDefinitionByName;

	public class AbstractPreloader extends MovieClip
	{
		// ___________________________________________________________________ CONSTANTS		
		
		// ___________________________________________________________________ CLASS PROPERTIES
		
		// ___________________________________________________________________ INSTANCE PROPERTIES
		
		// ___________________________________________________________________ GETTERS AND SETTERS
		
		// ___________________________________________________________________ CONSTRUCTOR
		
		public function AbstractPreloader() 
		{
			if (stage) {
				onAddedStage(null);
			} else {
				addEventListener(Event.ADDED_TO_STAGE, onAddedStage);
			}
			
			addEventListener(Event.ENTER_FRAME, oef);
			loaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
			
			addEventListener(PreloaderEvent.PRELOADER_COMPLETE, onPreloaderComplete);
			addEventListener(PreloaderEvent.PRELOADER_DESTROY, onPreloaderDestroy);
		}				
		
		// ___________________________________________________________________ PUBLIC METHODS
		
		protected function init():void
		{
			throw new IllegalOperationError("Abstract method: must be overriden in a subclass");
		}
		
		protected function destroy():void
		{
			throw new IllegalOperationError("Abstract method: must be overriden in a subclass");			
		}	
		
		protected function update(pct:Number):void
		{
			throw new IllegalOperationError("Abstract method: must be overriden in a subclass");
		}	
		
		// ___________________________________________________________________ PRIVATE METHODS
		
		private function initMain () : void 
		{
			var mainClass:Class = getDefinitionByName("Main") as Class;
			addChild(new mainClass() as DisplayObject);	
		}	
		
		// ___________________________________________________________________ EVENTS
		
		private function onAddedStage(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, onAddedStage);
			
			init();
		}
		
		private function oef(e:Event):void 
		{			
			update(loaderInfo.bytesLoaded / loaderInfo.bytesTotal);			
			
			if (currentFrame == totalFrames)
			removeEventListener(Event.ENTER_FRAME, oef);
		}			
		
		protected function onIOError(e:IOErrorEvent):void 
		{
			throw new IllegalOperationError("Abstract method: must be overriden in a subclass");
		}	
		
		private function onPreloaderComplete(e:PreloaderEvent):void 
		{
			removeEventListener(PreloaderEvent.PRELOADER_COMPLETE, onPreloaderComplete);			
			
			initMain();
		}
		
		private function onPreloaderDestroy(e:PreloaderEvent):void 
		{
			removeEventListener(PreloaderEvent.PRELOADER_DESTROY, onPreloaderDestroy);
			loaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
			
			destroy();
		}
	}
}

